package code.google.jcontainer.annotation;

import code.google.jcontainer.resolver.AnnotationResolver;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Used to declare the resolveClass and when for managed annotation.
 * take a look at {@link code.google.jcontainer.support.log.Log} or {@link code.google.jcontainer.support.intercept.Intercept} for examples.
 *
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 */
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Resolve {

    /**
     * Specify Annotation Resolver class for the annotated annotation
     * the resolveClass should implement the corresponding {@link code.google.jcontainer.resolver.ClassAnnotationResolver} and {@link code.google.jcontainer.resolver.MethodAnnotationResolver} and {@link code.google.jcontainer.resolver.FieldAnnotationResolver}}  
     */
    Class<? extends AnnotationResolver> resolverClass();

    /**
     * Specify when to resolve the annotated annotation.
     * {@link code.google.jcontainer.annotation.Resolve.WHEN} is a public inner enum class to define the phase of resolving the annotation
     */
    WHEN[] when();

    /**
     * A enum class to define when to resolve annotation
     */
    public static enum WHEN {
        /**
         * Resolve the annotated annotation before constructing component
         */
        BEFORE_CONSTRUCT(1),
        /**
         * Resolve the annotated annotation after constructing component
         */
        AFTER_CONSTRUCT(2),
        /**
         * Resolve the annotated annotation before invoking a method of component
         */
        BEFORE_METHOD(4),
        /**
         * Resolve the annotated annotation after invoking a method of component
         */
        AFTER_METHOD(8);

        private int intValue;

        WHEN(int intValue) {
            this.intValue = intValue;
        }

        public int getIntValue(){
            return intValue;
        }

        public boolean equals(WHEN when) {
            return this.intValue == when.getIntValue();
        }
    }
}